home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / lcsum.asm < prev    next >
Assembly Source File  |  1994-08-20  |  2KB  |  57 lines

  1.     IDNT        lcsum.asm
  2.  
  3.     CSECT        text
  4.     XDEF        _lcsum
  5. ;
  6. ;  Amazing, incredible, hyper-optimized Internet checksum subroutine!
  7. ;
  8. ;  Compute the 1's complement sum of data buffer.  Called from C as:-
  9. ;
  10. ;    unsigned short lcsum(unsigned short *buf, unsigned short cnt);
  11. ;
  12.  
  13. _lcsum:
  14.         MOVE.L    4(A7),A0        ; get pointer to data block
  15.         MOVE.L    8(A7),D1        ; get number of 16bit words to sum
  16.         MOVE        D2,A1            ; save D2 in a volitile register
  17.         MOVE        D1,D2            ; save a copy of the count
  18.         LSR.L        #1,D1            ; convert from words to longs
  19.         MOVEQ.L    #0,D0            ; D0 used to accumulate the sum, clear CC
  20.         BRA.S        endl            ; jump to end of loop to start things off
  21.  
  22. ;
  23. ; Take advantage of 68010 loop mode cache and add 2 words at a time until
  24. ; a carry propagates out.  68020 users win 'cause of instruction cache.
  25. ; 68000 users lose (though not nearly as much as 8086 folks!)
  26. ;
  27.  
  28. loop:    
  29.          ADD.L        (A0)+,D0        ; add two words in
  30. endl:    
  31.         DBCS        D1,loop
  32.         BCC.S        done            ; jump if done
  33.         ADDQ.L    #1,D0            ; add in carry
  34.         BRA.S        endl            ; resume loop
  35. done:
  36.         BTST        #0,D2            ; was word count odd?
  37.         BEQ.S        done2
  38.  
  39.         MOVEQ.L    #0,D2
  40.         MOVE.W    (A0),D2        ; get the last word
  41.         ADD.L        D2,D0            ; add it in
  42.         BCC.S        done2            ; did that cause a carry?
  43.         ADDQ.L    #1,D0            ; yes
  44. done2:
  45.         MOVE.L    A1,D2            ; restore register
  46.  
  47.         MOVE.L    D0,D1            ; get copy of sum                     D0=ABCD D1=ABCD
  48.         SWAP.W    D1                ; into low order part of D1      D0=ABCD D1=CDAB
  49.         AND.L        #$FFFF,D1    ; zap (is this necessary?)       D0=ABCD D1=00AB
  50.         ADD.W        D0,D1            ; two halfs of sum together
  51.         MOVEQ.L    #0,D0
  52.         ADDX.W    D0,D1            ; get last carry
  53.         MOVE.W    D1,D0
  54.         RTS
  55.  
  56.         END
  57.